/**
  gulp完成的任务：
  1、启动webserver
  2、编译sass, less
  3、CommonJS模块化
  4、Mock数据
  5、版本号控制
  6、打包压缩
  7、版本切换
 */

var gulp = require('gulp')

var webserver = require('gulp-webserver')

var sass = require('gulp-sass')

var webpack = require('gulp-webpack')

var named = require('vinyl-named')

var proxy = require('http-proxy-middleware')

var watch = require('gulp-watch')

var gulpSequence = require('gulp-sequence')

var $ = require('gulp-load-plugins')()

var del = require('del')

var rev = require('gulp-rev')
var revCollector = require('gulp-rev-collector')

var mininist = require('minimist')
var gulpif = require('gulp-if') //管道（pipe）内使用if
 // 环境变量，对应package.json
 // "dev": "gulp --env development",
 // "build": "gulp --env production"
 //可使用npm run dev 直接运行
var knownOpitions = { 
  string: 'env',
  default: {
    env: process.env.NODE_ENV || 'production'
  }
}
var option = mininist(process.argv.slice(2), knownOpitions) //process.argv：当前进程的命令行参数数组。


// 启动 webserver
gulp.task('webserver', function () {
  gulp.src('./build/dev')
    .pipe(webserver({ //服务器
      host: 'localhost', // 域名
      port: 4000,    //端口
      directoryListing: { 
        enable: true, //是否显示目录，false则默认为直接进入index.html
        path: './build/dev' //可访问的目录（除这个目录外为非法访问）
      },
      livereload: true, //热部署

      middleware: [ //中间件
      	//拉勾网m站接口
        proxy('/api', { //本地访问入口标识
          target: 'https://m.lagou.com/', //跳转目标地址
          changeOrigin: true, //是否重定向
          pathRewrite: { //重写路径
            '^/api': ''
          }
        }),
		    //使用json-server模拟了后台返回的数据，安装npm i json-server -g
        //启动：json-server src/mock/mock.js -p 9000
        proxy('/vip', { 
          target: 'http://localhost:9000/',
          changeOrigin: true,
          pathRewrite: {
            '^/vip': ''
          }
        })
      ]
    }))
})

// copyhtml
gulp.task('copyhtml', function () {
  if (option.env === 'production') { //若环境变量为生成环境，对css与js文件进行改名（版本控制）
    gulp.src(['./build/prd/rev/**/*.json', './src/*.html']) //[记录对应文件名的json文件，html]
    .pipe(revCollector()) //对应json对html中的应用进行改名
    .pipe($.minifyHtml()) //压缩
    .pipe(gulp.dest('./build/prd/'))
  } else {
    gulp.src(['./src/*.html'])
      .pipe(gulp.dest('./build/dev/'))
  }
})

// copyimage
gulp.task('copyimage', function () {
  gulp.src('./src/images/**/*')
    .pipe(gulpif(option.env !== 'production', gulp.dest('./build/dev/images')))
    .pipe(gulpif(option.env === 'production', gulp.dest('./build/prd/images')))
})

// copymock
gulp.task('copymock', function () {
  gulp.src('./src/mock/**/*')
    .pipe(gulpif(option.env !== 'production', gulp.dest('./build/dev/mock')))
})

// 编译scss
var cssPath = [
  './src/styles/app.scss',
  './src/styles/app-search.scss',
  './src/styles/app-mine.scss'
]
gulp.task('packscss', function () {
  gulp.src('./src/styles/*.scss')
    .pipe(sass().on('error', sass.logError))//使sass编译出错时服务器不会停止
    .pipe(gulpif(option.env === 'production', $.minifyCss()))
    .pipe(gulpif(option.env === 'production', rev())) //生成带md5编号的文件
    .pipe(gulpif(option.env !== 'production', gulp.dest('./build/dev/styles')))
    .pipe(gulpif(option.env === 'production', gulp.dest('./build/prd/styles')))
    .pipe(gulpif(option.env === 'production', rev.manifest())) //生成manifest.json
    .pipe(gulpif(option.env === 'production', gulp.dest('./build/prd/rev/styles')))
})

// 引入gulp-webpack, 实现CommonJS 模块化开发 chunk
var jsPath = [
  './src/scripts/app.js',
  './src/scripts/app-search.js',
  './src/scripts/app-mine.js'
]
gulp.task('packjs', function () {
  gulp.src(jsPath)
    .pipe(named()) //获取*.js 文件名，vinyl-named模块的使用
    .pipe(webpack({ //进行打包操作
      output: {
        filename: '[name].js' //输出的文件名，name对应获取的文件名
      },
      module: {
        loaders: [
          {
            test: /\.js$/,          //正则筛选js文件
            loader: 'imports-loader',//使用imports-loader对js文件进行加载
            exclude: './node_modules'//忽略某些目录|文件
          },
          {
            test: /\.string$/,
            loader: 'string-loader' //把任意的资源文件打包成可require的字符串模板，加载string
          }
        ]
      }
    }))
    .pipe(gulpif(option.env === 'production', $.uglify()))
    .pipe(gulpif(option.env === 'production', rev()))
    .pipe(gulpif(option.env !== 'production', gulp.dest('./build/dev/scripts')))
    .pipe(gulpif(option.env === 'production', gulp.dest('./build/prd/scripts')))
    .pipe(gulpif(option.env === 'production', rev.manifest()))
    .pipe(gulpif(option.env === 'production', gulp.dest('./build/prd/rev/scripts')))
})

gulp.task('watch', function () {
  watch('./src/styles/**/*', { //gulp-watch包的使用
    events: ['add', 'change', 'unlink']
  }, function () {
    gulpSequence('packscss')()
  })
  watch('./src/scripts/**/*.js', {
    events: ['add', 'change', 'unlink']
  }, function () {
    gulpSequence(['packjs'])()
  })
  watch('./src/templates/**/*.string', {
    events: ['add', 'change', 'unlink']
  }, function () {
    gulpSequence(['packjs'])()
  })
  watch('./src/*.html', {
    events: ['add', 'change', 'unlink']
  }, function () {
    gulpSequence(['copyhtml'])()
  })
  watch('./src/images/**/*', {
    events: ['add', 'change', 'unlink']
  }, function () {
    gulpSequence(['copyimage'])()
  })
  watch('./src/mock/**/*', {
    events: ['add', 'change', 'unlink']
  }, function () {
    gulpSequence(['copymock'])()
  })
})

gulp.task('clear', del.bind(null, ['./build/**/*'], { //删除
  force: true
}))

gulp.task('pack', function (cb) {
  if (option.env === 'production') {
    gulpSequence(['packscss', 'packjs', 'copymock', 'copyimage'], 'copyhtml')(cb) //cb为回调函数，gulp-sequence中数组表示并行，非数组表示串行
  } else {
    gulpSequence(['packscss', 'packjs', 'copyhtml', 'copymock', 'copyimage'])(cb)
  }
})

gulp.task('default', ['webserver', 'pack', 'watch'], function () {
  console.log('done.')
})
